//
//  HttpClient.m
//  ITV
//
//  Created by inphase on 17/4/5.
//  Copyright © 2017年 inphase. All rights reserved.
//

#import "HttpClient.h"
#import "HTTPClientConfig.h"

static Class defaultResponseHandlerClass;
static Class defaultParameterHandlerClass;
static Class defaultURLHandlerClass;


@implementation HttpClient

+(void)setDefaultURLHandlerClass:(Class)classType {
    defaultURLHandlerClass = classType;
}

+(void)setDefaultResponseHandlerClass:(Class)classType {
    defaultResponseHandlerClass = classType;
}

+(void)setDefaultParameterHandlerClass:(Class)classType {
    defaultParameterHandlerClass = classType;
}

+(void)load {
    defaultURLHandlerClass = [DefaultURLHandler class];
    defaultParameterHandlerClass = [DefaultParameterHandler class];
    defaultResponseHandlerClass = [DefaultResponseHandler class];
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        
        _urlHandler = [[defaultURLHandlerClass alloc]init];
        _parameterHandler = [[defaultParameterHandlerClass alloc]init];
        _responseHandler = [[defaultResponseHandlerClass alloc]init];
        
        _timeoutInterval = [[HTTPClientConfig sharedHTTPClientConfig] timeoutInterval];
        _stringEncoding = NSUTF8StringEncoding;
        
        _manager = [AFHTTPSessionManager manager];
        
        _requestSerializer = [AFHTTPRequestSerializer serializer];
        _responseSerializer = [AFHTTPResponseSerializer serializer];
        
        _requestSerializer.stringEncoding =
        _responseSerializer.stringEncoding =
        _stringEncoding;
        
        _requestSerializer.timeoutInterval = _timeoutInterval;
        
        _manager.requestSerializer = _requestSerializer;
        _manager.responseSerializer = _responseSerializer;
        
    }
    return self;
}

-(id)copyWithZone:(NSZone *)zone {
    
    HttpClient *client = [[super class]allocWithZone:zone];
    client.manager = [self.manager copyWithZone:zone];
    client.requestSerializer = [client.manager.requestSerializer copyWithZone:zone];
    client.responseSerializer = [client.manager.responseSerializer copyWithZone:zone];
    client.timeoutInterval = _timeoutInterval;
    client.stringEncoding = _stringEncoding;
    
    client.urlHandler = _urlHandler;
    client.parameterHandler = _parameterHandler;
    client.responseHandler = _responseHandler;
    
    return client;
}


+(HttpClient *)client {
    
    static dispatch_once_t onceToken;
    static HttpClient *client = nil;
    dispatch_once(&onceToken, ^{
        client = [[HttpClient alloc]init];
    });
    // 原型设计
    return [client copy];
}

-(void)setTimeoutInterval:(NSTimeInterval)timeoutInterval {
    
    _timeoutInterval = timeoutInterval;
    _requestSerializer.timeoutInterval = timeoutInterval;
}

-(void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer {
    
    _requestSerializer = requestSerializer;
    _manager.requestSerializer = requestSerializer;
}

-(void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer {
    
    _responseSerializer = responseSerializer;
    _manager.responseSerializer = responseSerializer;
}

-(NSURLSessionTask *)POST:(NSString *)url
               parameters:(id)parameters
            responseClass:(Class)classType
                  success:(void (^)(NSURLSessionTask *, id))success
                  failure:(void (^)(NSURLSessionTask *, NSError *))failure {
    
    return [self POST:url parameters:parameters header:nil responseClass:(Class)classType success:success failure:failure];
}

-(NSURLSessionTask *)POST:(NSString *)url
               parameters:(id)parameters
                   header:(NSDictionary *) header
            responseClass:(Class)classType
                  success:(void (^)(NSURLSessionTask *, id))success
                  failure:(void (^)(NSURLSessionTask *, NSError *))failure {
    
    return [self requestWitMethod:@"POST"
                              url:url
                       parameters:parameters
                           header:header
                    responseClass:classType
                          success:success
                          failure:failure];
}


-(NSURLSessionTask *)GET:(NSString *)url
              parameters:(id)parameters
           responseClass:(Class)classType
                 success:(void (^)(NSURLSessionTask *, id))success
                 failure:(void (^)(NSURLSessionTask *, NSError *))failure {
    
    return [self GET:url parameters:parameters header:nil responseClass:classType success:success failure:failure];
}

-(NSURLSessionTask *)GET:(NSString *)url
              parameters:(id)parameters
                  header:(NSDictionary *) header
           responseClass:(Class)classType
                 success:(void (^)(NSURLSessionTask *, id))success
                 failure:(void (^)(NSURLSessionTask *, NSError *))failure {
    
    return [self requestWitMethod:@"GET"
                              url:url
                       parameters:parameters
                           header:header
                    responseClass:classType
                          success:success
                          failure:failure];
}


-(NSURLSessionTask *) POSTWithToken:(NSString*) url
                         parameters:(id) parameters
                      responseClass:(Class) classType
                            success:(void (^)(NSURLSessionTask *operation, id responseObject))success
                            failure:(void (^)(NSURLSessionTask *operation, NSError *error))failure {
    return [self requestWitMethod:@"POST"
                              url:url
                       parameters:parameters
                           header:nil
                    responseClass:classType
                          success:success
                          failure:failure];
    
}

-(NSURLSessionTask *) GETWithToken:(NSString*) url
                        parameters:(id) parameters
                     responseClass:(Class) classType
                           success:(void (^)(NSURLSessionTask *operation, id responseObject))success
                           failure:(void (^)(NSURLSessionTask *operation, NSError *error))failure {
    return [self requestWitMethod:@"GET"
                              url:url
                       parameters:parameters
                           header:nil
                    responseClass:classType
                          success:success
                          failure:failure];
    
}

- (NSURLSessionTask *)POST:(NSString *)URLString
                parameters:(id)parameters
                   success:(void (^)(NSURLSessionTask *operation, id responseObject))success
                   failure:(void (^)(NSURLSessionTask *operation, NSError *error))failure {
    
    return [self POST:URLString parameters:parameters header:nil success:success failure:failure];
}

- (NSURLSessionTask *)POST:(NSString *)URLString
                parameters:(id)parameters
                    header:(NSDictionary *) header
                   success:(void (^)(NSURLSessionTask *operation, id responseObject))success
                   failure:(void (^)(NSURLSessionTask *operation, NSError *error))failure {
    
    return [self requestWitMethod:@"POST"
                              url:URLString
                       parameters:parameters
                           header:header
                    responseClass:nil
                          success:success
                          failure:failure];
}

-(NSURLSessionTask *)GET:(NSString *)URLString
              parameters:(id)parameters
                 success:(void (^)(NSURLSessionTask *, id))success
                 failure:(void (^)(NSURLSessionTask *, NSError *))failure {
    
    return [self GET:URLString parameters:parameters header:nil success:success failure:failure];
}

-(NSURLSessionTask *)GET:(NSString *)URLString
              parameters:(id)parameters
                  header:(NSDictionary *) header
                 success:(void (^)(NSURLSessionTask *, id))success
                 failure:(void (^)(NSURLSessionTask *, NSError *))failure {
    
    return [self requestWitMethod:@"GET"
                              url:URLString
                       parameters:parameters
                           header:header
                    responseClass:nil
                          success:success
                          failure:failure];
}

- (NSURLSessionTask *)GETWithToken:(NSString *)URLString
                        parameters:(id)parameters
                           success:(void (^)(NSURLSessionTask *operation, id responseObject))success
                           failure:(void (^)(NSURLSessionTask *operation, NSError *error))failure{
    
    return [self requestWitMethod:@"GET"
                              url:URLString
                       parameters:parameters
                           header:nil
                    responseClass:nil
                          success:success
                          failure:failure];
}
- (NSURLSessionTask *)POSTWithToken:(NSString *)URLString
                         parameters:(id)parameters
                            success:(void (^)(NSURLSessionTask *operation, id responseObject))success
                            failure:(void (^)(NSURLSessionTask *operation, NSError *error))failure {
    
    return [self requestWitMethod:@"POST"
                              url:URLString
                       parameters:parameters
                           header:nil
                    responseClass:nil
                          success:success
                          failure:failure];
}

-(NSURLSessionTask *)requestWitMethod:(NSString*) method
                                  url:(NSString *)url
                           parameters:(id)parameters
                               header:(NSDictionary *) header
                        responseClass:(Class)classType
                              success:(void (^)(NSURLSessionTask *, id))success
                              failure:(void (^)(NSURLSessionTask *, NSError *))failure {
    
    
    
    url = [_urlHandler fullURLWithKey:url];
    NSDictionary *finalParameter = [_parameterHandler parameterWithDictionary:parameters];
    header = [_parameterHandler headerWithDictionary:header];
    
    if (header) {
        for (NSString *key in header) {
            [_requestSerializer setValue:header[key] forHTTPHeaderField:key];
        }
    }
    
    if ([method isEqualToString:@"POST"]) {
        NSURLSessionTask *operation = [_manager POST:url
                                          parameters:finalParameter
                                            progress:nil
                                             success:[_responseDelegate success:success failure:failure responseClass:classType]
                                             failure:[_responseDelegate failure:failure]];
        self.sessionTask = operation;
        
    }else {
        NSURLSessionTask *operation = [_manager GET:url
                                         parameters:finalParameter
                                           progress:nil
                                            success:[_responseDelegate success:success failure:failure responseClass:classType]
                                            failure:[_responseDelegate failure:failure]];
        self.sessionTask = operation;
    }
    
    return self.sessionTask;
}

-(void)cancel {
    
    if (self.sessionTask) {
        [self.sessionTask cancel];
    }
}


@end
